package com.tyx.chargingpile.controller;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.tyx.chargingpile.Enum.HttpServiceExceptionEume;
import com.tyx.chargingpile.cache.SocketChannelMap;
import com.tyx.chargingpile.service.ChargingPileService;
import com.tyx.chargingpile.service.OutPutService;
import com.tyx.chargingpile.service.exception.ServiceExcep;
import com.tyx.chargingpile.service.impl.*;
import com.tyx.chargingpile.util.FastJsonUtils;
import com.tyx.chargingpile.vo.ChargingPileInfo;
import com.tyx.chargingpile.vo.RespondResult;
import io.netty.channel.ChannelHandlerContext;
import org.apache.http.util.TextUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/chargingPile")
public class ChargingPileController {

    @Autowired
    private OutPutService outPutService;
    @Autowired
    private ChargingPileOpenDown chargingPileOpenDown;
    @Autowired
    private ChargingPileCloseDown chargingPileCloseDown;
    @Autowired
    private ChargingPileElectricPriceDown chargingPileElectricPriceDown;
    @Autowired
    private ChargingPileCardMsgReportCheckResultDown chargingPileCardMsgReportCheckResultDown;
    @Autowired
    private ChargingPileVinCodeCheckResultDown chargingPileVinCodeCheckResultDown;

    private final static Logger LOGGER = LoggerFactory.getLogger(ChargingPileController.class);
    /**
     * 失败，校验不通过，返回400
     * @param o
     * @return
     */
    @RequestMapping(value = "/web_api",produces = "application/json;charset=UTF-8",method = RequestMethod.POST)
    public Object webApi(@RequestBody Map o){
        System.out.println(FastJsonUtils.collectToString(o));
        if(o == null){
//            return RespondResult.ERROR(HttpServiceExceptionEume.PARAMETERERROR);
            LOGGER.info("前置http接口：接收到的参数为空");
            return 400;
        }
        Integer MainCMD = (Integer) o.get("MainCMD");
        if (StringUtils.isEmpty(MainCMD)){
            LOGGER.info("前置http接口：MainCMD参数为空");
            return 400;
        }
        Integer SubCMD = (Integer) o.get("SubCMD");
        if(StringUtils.isEmpty(SubCMD)){
//            return RespondResult.ERROR(HttpServiceExceptionEume.REQUESTINSTRUCTIONERROR);
            LOGGER.info("前置http接口：SubCMD参数为空");
            return 400;
        }
//        RespondResult respondResult = null;
        LOGGER.info("前置http接口--接受到的参数" + o.toString());
        Map data = (Map) o.get("Data");
        int result;
        switch (SubCMD){
            case 1:
                // 获取设备当前状态信息
                return getChargingPileInfo(data);
//                return RespondResult.OK(chargingPileInfo);
            case 2:
                // 开启充电
                result = openCharge(data);
                return result;
            case 3:
                // 结束充电
                result = closeCharge(data);
                return result;
            case 4:
                // 获取桩群信息
                return getChargingPileInfoList(data);
            case 10:
                result = electricPrice(data);
                return result;
            case 12:
                // 卡鉴权结果返回
                result = reportCheckResult(data);
                return result;
            case 14:
                result = vinCodeCheckResult(data);
                return result;
            default:
                break;
        }
        return 400;
    }

    public Object getChargingPileInfo(Map data){
        // 获取设备当前状态信息
        if(data == null){
            LOGGER.info("前置http接口--获取设备当前状态信息，data参数为空");
            return 400;
        }
        String pileId = (String) data.get("PileId");
        if(StringUtils.isEmpty(pileId)){
            LOGGER.info("前置http接口--获取设备当前状态信息，PileId参数为空");
            return 400;
        }
        ChargingPileInfo chargingPileInfo = outPutService.getChargingPileInfo(pileId);
        if(chargingPileInfo == null){
            LOGGER.info("前置http接口--获取设备当前状态信息，pileid=" + pileId + ",信息为空");
            return 400;
        }
        JSONObject dataJson = (JSONObject) JSON.toJSON(chargingPileInfo);
        JSONObject returnJson = new JSONObject();
        returnJson.put("MainCMD",68);
        returnJson.put("SubCMD",1);
        returnJson.put("Data",dataJson);
        String respondResult = returnJson.toJSONString();
        LOGGER.info("前置http接口--获取设备当前状态信息，反参:" + respondResult);
        return returnJson;
    }

    /**
     * 开启充电
     * @param data
     * @return
     */
    private int openCharge(Map data){
        if (data == null){
            LOGGER.info("前置http接口--远程开启放电，data参数为空" );
            return 400;
        }
        String pileNum = (String) data.get("PileId");
        String gunpointNum = (String) data.get("ChargePortIndex");
        String orderNum = (String) data.get("Orderid");
        String chargeLimit = (String) data.get("ChargeLimit");
        String chargeMoney = (String) data.get("ChargeMoney");
        String chargeMode = (String) data.get("ChargeMode");
        // 判断所有参数，不允许为空
        if (TextUtils.isEmpty(pileNum) || TextUtils.isEmpty(gunpointNum) || TextUtils.isEmpty(orderNum) || TextUtils.isEmpty(chargeLimit) || TextUtils.isEmpty(chargeMoney) || TextUtils.isEmpty(chargeMode)){
            return 400;
        }
        boolean isContains = SocketChannelMap.containsKey(pileNum);
        if (!isContains){
            LOGGER.info("前置http接口--远程开启放电，电桩编号为" + pileNum + ",查询不到相关通道信息" );
            return 400;
        }
        try {
            ChannelHandlerContext channelHandlerContext = (ChannelHandlerContext) SocketChannelMap.getChannelMap(pileNum);
            asyncExecute(chargingPileOpenDown,channelHandlerContext,data);
            return 200;
        } catch (Exception e) {
            e.printStackTrace();
            LOGGER.error("前置http接口--远程开启放电，异常：" + e.getMessage() );
            return 400;
        }
    }

    /**
     * 停止充电
     * @param data
     * @return
     */
    private int closeCharge(Map data){
        if (data == null){
            LOGGER.info("前置http接口--远程停止充电，data参数为空" );
            return 400;
        }
        String pileNum = (String) data.get("PileId");
        String gunpointNum = (String) data.get("ChargePortIndex");
        String orderNum = (String) data.get("Orderid");
        // 判断所有参数，不允许为空
        if (TextUtils.isEmpty(pileNum) || TextUtils.isEmpty(gunpointNum) || TextUtils.isEmpty(orderNum)){
            return 400;
        }
        boolean isContains = SocketChannelMap.containsKey(pileNum);
        if (!isContains){
            LOGGER.info("前置http接口--远程停止充电，电桩编号为" + pileNum + ",查询不到相关通道信息" );
            return 400;
        }
        try {
            ChannelHandlerContext channelHandlerContext = (ChannelHandlerContext) SocketChannelMap.getChannelMap(pileNum);
            asyncExecute(chargingPileCloseDown,channelHandlerContext,data);
            return 200;
        } catch (Exception e) {
            e.printStackTrace();
            LOGGER.error("前置http接口--远程停止充电，异常：" + e.getMessage() );
            return 400;
        }
    }

    /**
     * 电价下发
     * @return
     */
    private int electricPrice(Map data){
        // 电价下发
        if (data == null){
            LOGGER.info("前置http接口--电价下发，data参数为空" );
            return 400;
        }
        String pileNum = (String) data.get("PileId");
        boolean isContains = SocketChannelMap.containsKey(pileNum);
        if (!isContains){
            LOGGER.info("前置http接口--电价下发，电桩编号为" + pileNum + ",查询不到相关通道信息" );
            return 400;
        }
        String defaultPrice = (String) data.get("DefaultPrice");
        String firstTime = (String) data.get("FirstTime");
        String firstPrice = (String) data.get("FirstPrice");
        String secondTime = (String) data.get("SecondTime");
        String secondPrice = (String) data.get("SecondPrice");
        // 判断所有参数，不允许为空
        if (TextUtils.isEmpty(pileNum) || TextUtils.isEmpty(defaultPrice) || TextUtils.isEmpty(firstTime) || TextUtils.isEmpty(firstPrice) || TextUtils.isEmpty(secondTime) || TextUtils.isEmpty(secondPrice)){
            return 400;
        }
        try {
            ChannelHandlerContext channelHandlerContext = (ChannelHandlerContext) SocketChannelMap.getChannelMap(pileNum);
            asyncExecute(chargingPileElectricPriceDown,channelHandlerContext, data);
            return 200;
        } catch (ServiceExcep serviceExcep) {
            serviceExcep.printStackTrace();
            return 400;
        }
    }

    /**
     * 卡鉴权结果返回
     * @param data
     * @return
     */
    private int reportCheckResult(Map data){
        if (data == null){
            LOGGER.info("前置http接口--卡鉴权结果返回，data参数为空" );
            return 400;
        }
        String pileNum = (String) data.get("PileId");
        boolean isContains = SocketChannelMap.containsKey(pileNum);
        if (!isContains){
            LOGGER.info("前置http接口--卡鉴权结果返回，电桩编号为" + pileNum + ",查询不到相关通道信息" );
            return 400;
        }
        String gunpointNum = (String) data.get("ChargePortIndex");
        String cardNo = (String) data.get("CardId");
        String physicalId = (String) data.get("PhysicalId");
        String amountMoney = (String) data.get("AmountMoney");
        String authResult = (String) data.get("AuthResult");
        String errorCode = (String) data.get("ErrorCode");
        String locakStatus = (String) data.get("LocakStatus");
        // 判断所有参数，不允许为空
        if (TextUtils.isEmpty(pileNum) || TextUtils.isEmpty(gunpointNum) || TextUtils.isEmpty(cardNo) || TextUtils.isEmpty(physicalId) || TextUtils.isEmpty(amountMoney) || TextUtils.isEmpty(authResult)|| TextUtils.isEmpty(errorCode) || TextUtils.isEmpty(locakStatus)){
            return 400;
        }
        try {
            ChannelHandlerContext channelHandlerContext = (ChannelHandlerContext) SocketChannelMap.getChannelMap(pileNum);
            asyncExecute(chargingPileCardMsgReportCheckResultDown, channelHandlerContext, data);
            return 200;
        } catch (Exception e) {
            e.printStackTrace();
            return 400;
        }
    }

    private Object getChargingPileInfoList(Map data){
        if(data == null){
            LOGGER.info("前置http接口--获取桩群信息，data参数为空");
            return 400;
        }
        List<String> list = (List) data.get("PileId");
        if(StringUtils.isEmpty(list)){
            LOGGER.info("前置http接口--获取桩群信息，PileId参数为空");
            return 400;
        }
        JSONArray dataArray = new JSONArray();
        for (String str:
             list) {
            ChargingPileInfo chargingPileInfo = outPutService.getChargingPileInfo(str);
            JSONObject dataJson = (JSONObject) JSON.toJSON(chargingPileInfo);
            dataArray.add(dataJson);
        }
        JSONObject returnJson = new JSONObject();
        returnJson.put("MainCMD",68);
        returnJson.put("SubCMD",4);
        returnJson.put("Data",dataArray);
        String respondResult = returnJson.toJSONString();
        LOGGER.info("前置http接口--获取桩群信息，反参:" + respondResult);
        return returnJson;
    }

    /**
     * vin码鉴权结果返回
     * @param data
     * @return
     */
    private int vinCodeCheckResult(Map data){
        if (data == null){
            LOGGER.info("前置http接口--卡鉴权结果返回，data参数为空" );
            return 400;
        }
        String pileNum = (String) data.get("PileId");
        boolean isContains = SocketChannelMap.containsKey(pileNum);
        if (!isContains){
            LOGGER.info("前置http接口--vin码鉴权结果返回，电桩编号为" + pileNum + ",查询不到相关通道信息" );
            return 400;
        }
        String gunpointNum = (String) data.get("ChargePortIndex");
        String vin = (String) data.get("VIN");
        String amountMoney = (String) data.get("AmountMoney");
        String authResult = (String) data.get("AuthResult");
        String errorCode = (String) data.get("ErrorCode");
        // 判断所有参数，不允许为空
        if (TextUtils.isEmpty(pileNum) || TextUtils.isEmpty(gunpointNum) || TextUtils.isEmpty(vin) || TextUtils.isEmpty(amountMoney) || TextUtils.isEmpty(authResult)|| TextUtils.isEmpty(errorCode)){
            return 400;
        }
        try {
            ChannelHandlerContext channelHandlerContext = (ChannelHandlerContext) SocketChannelMap.getChannelMap(pileNum);
            asyncExecute(chargingPileVinCodeCheckResultDown, channelHandlerContext, data);
            return 200;
        } catch (Exception e) {
            e.printStackTrace();
            return 400;
        }
    }

    @Async
    public void asyncExecute(ChargingPileService chargingPileService,ChannelHandlerContext channelHandlerContext,Map data){
        try {
            chargingPileService.execute(channelHandlerContext,data);
        } catch (Exception e) {
            e.printStackTrace();
            LOGGER.error("前置http接口下发，异常：" + e.getMessage() );
        }
    }
}
